<!DOCTYPE html>
<html style="display: none;" lang="zh">
    <head><meta name="generator" content="Hexo 3.9.0">
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="utf-8">
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.5.2 -->
    <script>
        window.materialVersion = "1.5.2"
        // Delete localstorage with these tags
        window.oldVersion = [
            'codestartv1',
            '1.3.4',
            '1.4.0',
            '1.4.0b1',
            '1.5.0'
        ]
    </script>

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">














    <!-- Meta & Info -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

    <!-- Title -->
    
    <title>
        
            Docker | 
        
        fengweizan&#39;s BLOG
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/favicon.png">
    <link rel="icon" href="/img/favicon.png">

    <meta name="format-detection" content="telephone=no">
    <meta name="description" itemprop="description" content="my blog with material design">
    <meta name="keywords" content>
    <meta name="theme-color" content="#0097A7">

    <!-- Disable Fucking Bloody Baidu Tranformation -->
    <meta http-equiv="Cache-Control" content="no-transform">
    <meta http-equiv="Cache-Control" content="no-siteapp">

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import lsloader -->
    <script>(function(){window.lsloader={jsRunSequence:[],jsnamemap:{},cssnamemap:{}};lsloader.removeLS=function(a){try{localStorage.removeItem(a)}catch(b){}};lsloader.setLS=function(a,c){try{localStorage.setItem(a,c)}catch(b){}};lsloader.getLS=function(a){var c="";try{c=localStorage.getItem(a)}catch(b){c=""}return c};versionString="/*"+(window.materialVersion||"unknownVersion")+"*/";lsloader.clean=function(){try{var b=[];for(var a=0;a<localStorage.length;a++){b.push(localStorage.key(a))}b.forEach(function(e){var f=lsloader.getLS(e);if(window.oldVersion){var d=window.oldVersion.reduce(function(g,h){return g||f.indexOf("/*"+h+"*/")!==-1},false);if(d){lsloader.removeLS(e)}}})}catch(c){}};lsloader.clean();lsloader.load=function(f,a,b,d){if(typeof b==="boolean"){d=b;b=undefined}d=d||false;b=b||function(){};var e;e=this.getLS(f);if(e&&e.indexOf(versionString)===-1){this.removeLS(f);this.requestResource(f,a,b,d);return}if(e){var c=e.split(versionString)[0];if(c!=a){console.log("reload:"+a);this.removeLS(f);this.requestResource(f,a,b,d);return}e=e.split(versionString)[1];if(d){this.jsRunSequence.push({name:f,code:e});this.runjs(a,f,e)}else{document.getElementById(f).appendChild(document.createTextNode(e));b()}}else{this.requestResource(f,a,b,d)}};lsloader.requestResource=function(b,e,a,c){var d=this;if(c){this.iojs(e,b,function(h,f,g){d.setLS(f,h+versionString+g);d.runjs(h,f,g)})}else{this.iocss(e,b,function(f){document.getElementById(b).appendChild(document.createTextNode(f));d.setLS(b,e+versionString+f)},a)}};lsloader.iojs=function(d,b,g){var a=this;a.jsRunSequence.push({name:b,code:""});try{var f=new XMLHttpRequest();f.open("get",d,true);f.onreadystatechange=function(){if(f.readyState==4){if((f.status>=200&&f.status<300)||f.status==304){if(f.response!=""){g(d,b,f.response);return}}a.jsfallback(d,b)}};f.send(null)}catch(c){a.jsfallback(d,b)}};lsloader.iocss=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.iofonts=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.runjs=function(f,c,e){if(!!c&&!!e){for(var b in this.jsRunSequence){if(this.jsRunSequence[b].name==c){this.jsRunSequence[b].code=e}}}if(!!this.jsRunSequence[0]&&!!this.jsRunSequence[0].code&&this.jsRunSequence[0].status!="failed"){var a=document.createElement("script");a.appendChild(document.createTextNode(this.jsRunSequence[0].code));a.type="text/javascript";document.getElementsByTagName("head")[0].appendChild(a);this.jsRunSequence.shift();if(this.jsRunSequence.length>0){this.runjs()}}else{if(!!this.jsRunSequence[0]&&this.jsRunSequence[0].status=="failed"){var d=this;var a=document.createElement("script");a.src=this.jsRunSequence[0].path;a.type="text/javascript";this.jsRunSequence[0].status="loading";a.onload=function(){d.jsRunSequence.shift();if(d.jsRunSequence.length>0){d.runjs()}};document.body.appendChild(a)}}};lsloader.tagLoad=function(b,a){this.jsRunSequence.push({name:a,code:"",path:b,status:"failed"});this.runjs()};lsloader.jsfallback=function(c,b){if(!!this.jsnamemap[b]){return}else{this.jsnamemap[b]=b}for(var a in this.jsRunSequence){if(this.jsRunSequence[a].name==b){this.jsRunSequence[a].code="";this.jsRunSequence[a].status="failed";this.jsRunSequence[a].path=c}}this.runjs()};lsloader.cssfallback=function(e,c,b){if(!!this.cssnamemap[c]){return}else{this.cssnamemap[c]=1}var d=document.createElement("link");d.type="text/css";d.href=e;d.rel="stylesheet";d.onload=d.onerror=b;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(d,a)};lsloader.runInlineScript=function(c,b){var a=document.getElementById(b).innerText;this.jsRunSequence.push({name:c,code:a});this.runjs()}})();</script>

    <!-- Import queue -->
    <script>function Queue(){this.dataStore=[];this.offer=b;this.poll=d;this.execNext=a;this.debug=false;this.startDebug=c;function b(e){if(this.debug){console.log("Offered a Queued Function.")}if(typeof e==="function"){this.dataStore.push(e)}else{console.log("You must offer a function.")}}function d(){if(this.debug){console.log("Polled a Queued Function.")}return this.dataStore.shift()}function a(){var e=this.poll();if(e!==undefined){if(this.debug){console.log("Run a Queued Function.")}e()}}function c(){this.debug=true}}var queue=new Queue();</script>

    <!-- Import CSS -->
    
        <style id="material_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_css","/css/material.min.css?Z7a72R1E4SxzBKR/WGctOA==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
        <style id="style_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("style_css","/css/style.min.css?MKetZV3cUTfDxvMffaOezg==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>

        
            
                <style id="prettify_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("prettify_css","/css/prettify.min.css?zp8STOU9v89XWFEnN+6YmQ==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
                <style id="prettify_theme"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("prettify_theme","/css/prettify/github-v2.min.css?AfzKxt++K+/lhZBlSjnxwg==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
            
        

    

    

    <!-- Config CSS -->

<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    overflow-x: hidden !important;
  }
  
  code {
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body {
        background-color: #F5F5F5;
      }

      /* blog_info bottom background */
      #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text {
        background-color: #fff;
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


<!-- Import Font -->
<!-- Import Roboto -->

    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">


<!-- Import Material Icons -->


    <style id="material_icons"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_icons","/css/material-icons.css?pqhB/Rd/ab0H2+kZp0RDmw==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>




    <!-- Import jQuery -->
    
        <script>lsloader.load("jq_js","/js/jquery.min.js?qcusAULNeBksqffqUM2+Ig==", true)</script>
    

    <!-- WebAPP Icons -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="fengweizan&#39;s BLOG">
    <meta name="msapplication-starturl" content="https://fclehly.github.io/2019/06/19/Docker/">
    <meta name="msapplication-navbutton-color" content="#0097A7">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="fengweizan&#39;s BLOG">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Site Verification -->
    
    

    <!-- RSS -->
    

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="https://fclehly.github.io/2019/06/19/Docker/">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="Docker | fengweizan&#39;s BLOG">
    <meta property="og:image" content="/img/favicon.png">
    <meta property="og:description" content="my blog with material design">
    

    
        <meta property="article:published_time" content="Wed Jun 19 2019 22:50:57 GMT+0800">
        <meta property="article:modified_time" content="Fri Jul 05 2019 22:17:06 GMT+0800">
    

    <!-- The Twitter Card protocol -->
    <meta name="twitter:card" content="summary_large_image">

    <!-- Add canonical link for SEO -->
    
        <link rel="canonical" href="https://fclehly.github.io/2019/06/19/Docker/index.html">
    

    <!-- Structured-data for SEO -->
    
        


<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": "https://fclehly.github.io/2019/06/19/Docker/index.html",
    "headline": "Docker",
    "datePublished": "Wed Jun 19 2019 22:50:57 GMT+0800",
    "dateModified": "Fri Jul 05 2019 22:17:06 GMT+0800",
    "author": {
        "@type": "Person",
        "name": "FWZ",
        "image": {
            "@type": "ImageObject",
            "url": "/img/avatar.png"
        },
        "description": "Hi, nice to meet you"
    },
    "publisher": {
        "@type": "Organization",
        "name": "fengweizan&#39;s BLOG",
        "logo": {
            "@type":"ImageObject",
            "url": "/img/favicon.png"
        }
    },
    "keywords": "",
    "description": "my blog with material design",
}
</script>


    

    <!-- Analytics -->
    
    
    

    <!-- Custom Head --><!-- hexo-inject:begin --><!-- hexo-inject:end -->
    

</head>


    
        <body id="scheme-Paradox" class="lazy">
            <!-- hexo-inject:begin --><!-- hexo-inject:end --><div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->


    <!-- Left aligned menu below button -->
    
    
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#Abstract"><span class="post-toc-number">1.</span> <span class="post-toc-text">Abstract</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#Why"><span class="post-toc-number">2.</span> <span class="post-toc-text">Why</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#一致的运行环境"><span class="post-toc-number">2.1.</span> <span class="post-toc-text">一致的运行环境</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#持续交付和部署"><span class="post-toc-number">2.2.</span> <span class="post-toc-text">持续交付和部署</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#更轻松的迁移"><span class="post-toc-number">2.3.</span> <span class="post-toc-text">更轻松的迁移</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#更轻松的维护和扩展"><span class="post-toc-number">2.4.</span> <span class="post-toc-text">更轻松的维护和扩展</span></a></li></ol></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#VM-Vagrant-Docker"><span class="post-toc-number">3.</span> <span class="post-toc-text">VM, Vagrant, Docker</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#Docker的组成"><span class="post-toc-number">4.</span> <span class="post-toc-text">Docker的组成</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Docker-Image"><span class="post-toc-number">4.1.</span> <span class="post-toc-text">Docker Image</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Docker-Container"><span class="post-toc-number">4.2.</span> <span class="post-toc-text">Docker Container</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Docker-Registry"><span class="post-toc-number">4.3.</span> <span class="post-toc-text">Docker Registry</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Namespaces"><span class="post-toc-number">4.4.</span> <span class="post-toc-text">Namespaces</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Control-Groups"><span class="post-toc-number">4.5.</span> <span class="post-toc-text">Control Groups</span></a></li></ol></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#Dockerfile指令"><span class="post-toc-number">5.</span> <span class="post-toc-text">Dockerfile指令</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#指令格式"><span class="post-toc-number">5.1.</span> <span class="post-toc-text">指令格式</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#FROM"><span class="post-toc-number">5.2.</span> <span class="post-toc-text">FROM</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#RUN"><span class="post-toc-number">5.3.</span> <span class="post-toc-text">RUN</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#CMD"><span class="post-toc-number">5.4.</span> <span class="post-toc-text">CMD</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#EXPOSE"><span class="post-toc-number">5.5.</span> <span class="post-toc-text">EXPOSE</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#COPY"><span class="post-toc-number">5.6.</span> <span class="post-toc-text">COPY</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#ENTRYPOINT"><span class="post-toc-number">5.7.</span> <span class="post-toc-text">ENTRYPOINT</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#LABEL"><span class="post-toc-number">5.8.</span> <span class="post-toc-text">LABEL</span></a></li></ol></li></ol>
    </ul>
    




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        
            <!-- Random Thumbnail -->
            <div class="post_thumbnail-random mdl-card__media mdl-color-text--grey-50">
            <script type="text/ls-javascript" id="post-thumbnail-script">
    var randomNum = Math.floor(Math.random() * 19 + 1);

    $('.post_thumbnail-random').attr('data-original', '/img/random/material-' + randomNum + '.png');
    $('.post_thumbnail-random').addClass('lazy');
</script>

        
    
            <p class="article-headline-p">
                Docker
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/avatar.png" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>FWZ</strong>
        <span>6月 19, 2019</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    

    <!-- Share -->
    
        <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=Docker&url=https://fclehly.github.io/2019/06/19/Docker/index.html&pic=https://fclehly.github.io/img/favicon.png&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=Docker&url=https://fclehly.github.io/2019/06/19/Docker/index.html&via=FWZ" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=https://fclehly.github.io/2019/06/19/Docker/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=https://fclehly.github.io/2019/06/19/Docker/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

    
</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <h2 id="Abstract"><a href="#Abstract" class="headerlink" title="Abstract"></a>Abstract</h2><p>Docker是一个开源的容器引擎，可以将应用软件和应用所需的依赖打包在一起，形成一个标准化单元，类似于Java基于jvm的<em>write once, run anywhere</em>， docker可以实现<em>build once, run anywhere</em>。最近几年，微服务架构火热，而在大型企业中，微服务的运维由于服务的数量比较多而进展困难，容器化服务势在必行。服务容器化使应用程序能够从组件快速组装到发布，消除了开发和QS和IT的摩擦。容器是微服务的基石，没有容器化的微服务是没有灵魂的。docker让容器化操作变得简单，docker的出现让大型的微服务架构得以流行，而微服务的火热又促进了docker发展。</p>
<h2 id="Why"><a href="#Why" class="headerlink" title="Why"></a>Why</h2><h3 id="一致的运行环境"><a href="#一致的运行环境" class="headerlink" title="一致的运行环境"></a>一致的运行环境</h3><blockquote>
<p>开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致，导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境，确保了应用运行环境一致性，从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。</p>
</blockquote>
<h3 id="持续交付和部署"><a href="#持续交付和部署" class="headerlink" title="持续交付和部署"></a>持续交付和部署</h3><blockquote>
<p>对开发和运维（DevOps）人员来说，最希望的就是一次创建或配置，可以在任意地方正常运行。<br>使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建，并结合 持续集成(Continuous Integration) 系统进行集成测试，而运维人员则可以直接在生产环境中快速部署该镜像，甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。<br>而且使用 Dockerfile 使镜像构建透明化，不仅仅开发团队可以理解应用运行环境，也方便运维团队理解应用运行所需条件，帮助更好的生产环境中部署该镜像。</p>
</blockquote>
<h3 id="更轻松的迁移"><a href="#更轻松的迁移" class="headerlink" title="更轻松的迁移"></a>更轻松的迁移</h3><blockquote>
<p>由于 Docker 确保了执行环境的一致性，使得应用的迁移更加容易。Docker 可以在很多平台上运行，无论是物理机、虚拟机、公有云、私有云，甚至是笔记本，其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用，迁移到另一个平台上，而不用担心运行环境的变化导致应用无法正常运行的情况。</p>
</blockquote>
<h3 id="更轻松的维护和扩展"><a href="#更轻松的维护和扩展" class="headerlink" title="更轻松的维护和扩展"></a>更轻松的维护和扩展</h3><blockquote>
<p>Docker 使用的分层存储以及镜像的技术，使得应用重复部分的复用更为容易，也使得应用的维护更新更加简单，基于基础镜像进一步扩展镜像也变得非常简单。此外，Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像，既可以直接在生产环境使用，又可以作为基础进一步定制，大大的降低了应用服务的镜像制作成本。</p>
</blockquote>
<h2 id="VM-Vagrant-Docker"><a href="#VM-Vagrant-Docker" class="headerlink" title="VM, Vagrant, Docker"></a>VM, Vagrant, Docker</h2><p>最开始，大家就想着直接把整个系统打包再部署，即虚拟机技术，保证了系统和环境的稳定，减少了大量手工操作。但是，缺点也是有的，那就是无法自动化打包过程，于是<a href="https://www.vagrantup.com/">Vargrant</a>被做了出来，Vargrant使用了vargrantfile文件给开发者提供了定义自动化构建VM镜像的功能。但是，还是有缺点，首先，打包出来的镜像太大，包含了过多不需要使用的依赖；其次，服务启动必须等得VM的系统启动完成后才能启动服务。<br>为了解决VM的缺点，Docker被开发了出来，它提供了系统上的进程级别的虚拟化技术。与VM需要虚拟化整个硬件和操作系统不同，Docker是直接基于宿主机的操作系统进行虚拟化，性能几乎没有损耗。具体结构差异如下：</p>
<pre><code>虚拟机：
    +------------+-------------+
    | App A      |  App B      |
    +------------+-------------+
    | Libs       |  Libs       |
    +------------+-------------+
    |Guest OS    |  Guest OS   |
    +------------+-------------+
    |       Hypervisor         |
    +--------------------------+
    |        HOST OS           |
    +--------------------------+
    |         SERVER           |
    +--------------------------+

Docker：
    +------------+-------------+
    | App A      |  App B      |
    +------------+-------------+
    | Libs       |  Libs       |
    +------------+-------------+
    |       Docker Engine      |
    +--------------------------+
    |        HOST OS           |
    +--------------------------+
    |         SERVER           |
    +--------------------------+

</code></pre><h2 id="Docker的组成"><a href="#Docker的组成" class="headerlink" title="Docker的组成"></a>Docker的组成</h2><p>docker主要由以下组件组成：</p>
<ul>
<li>docker client</li>
<li>docker daemon</li>
<li>docker image</li>
<li>docker container</li>
<li>docker registry</li>
</ul>
<p>Docker本身是C/S架构，C端是docker client，S端是docker daemon，docker daemon管理者docker image和docker container，docker index提供镜像索引以及用户认证的功能，docker registry在远程存放镜像，大致架构如下：</p>
<pre><code>

                           +-----------------+
                           | Docker Daemon   |
        ,---.              |  -------------- |                )------------------(
       /     \             |  Container1     |                |                  |
      / Docker\            |                 |--------------- |  Docker Registry |
     (  Client )---------- |  Container2     |                |                  |
      \       /            |                 |                )------------------(
       \     /             |  Container3     |                          |
        `---&#39;              |                 |                          |
     docker pull           |  .......        |                          |
     docker run            |                 |                          |
     docker build          +-----------------+                          |
     docker ...                     |                                   |
                                    |                                   |
                            +----------------+                          |
                            |  Docker Index  |--------------------------+
                            +----------------+
</code></pre><h3 id="Docker-Image"><a href="#Docker-Image" class="headerlink" title="Docker Image"></a>Docker Image</h3><p>docker image是docker容器的基石，保存了docker启动的各种条件，docker container的启动必须基于一个docker image。Docker image位于docker生命周期的构建和打包阶段。<br>docker使用了union mount的方式构建镜像，采用了ufs的模型。就是docker一次性加载多个文件系统形成一个文件系统层叠的形式，但是在外部看来容器只有一个文件系统可用，docker将这样的文件系统称为docker image。<br>docker image是一个层层叠加的只读文件系统。最底部是bootfs，即引导文件系统，当容器启动后，引导文件系统将会被卸载。bootfs之上是rootfs，rootfs可以是ubuntu/centos/debian/fedora，与虚拟机启动后由只读状态变为读写状态不同，docker的rootfs永远是只读。</p>
<pre><code>Docker的UFS示例：
 +---------------+
 |  add django   |
 +---------------+
 |  add python3  |
 +---------------+
 |rootfs(ubuntu) |
 +---------------+
 |     bootfs    |
 +---------------+

</code></pre><h3 id="Docker-Container"><a href="#Docker-Container" class="headerlink" title="Docker Container"></a>Docker Container</h3><p>Docker Container是Docker的执行单元，通过镜像来启动。Docker container位于docker生命周期的启动和执行阶段。<br>Docker Container基于镜像启动时，会在镜像构建出的ufs上再添加一个writable layer，一个可写层。当容器刚启动时，该读写层是空的，当容器状态发生改变时，读写层才会有变化。比如当需要修改一个文件时，docker把改文件从下层的只读文件系统中复制到读写层，再进行修改，该文件的只读版本仍然存在，但是已经被读写层上的副本隐藏起来了。这就是Docker中重要的技术<strong>Copy on Write</strong>（中文翻译为写时复制），每个只读镜像层永远都是只读的，不会变化，当创建出一个新容器时，docker会构建出一个镜像栈，在栈的顶层增加读写层，并与底下的只读层和一些数据就构成了一个容器。容器的分层框架能够使我们快速的构建镜像并发布应用程序。</p>
<pre><code>Docker container创建的镜像栈

 +---------------+
 | add my app    |  读写层(copy on write)
 +---------------+
 |  add django   |  Read Only
 +---------------+
 |  add python3  |  Read Only
 +---------------+
 |rootfs(ubuntu) |  Read Only
 +---------------+
 |     bootfs    |  Read Only
 +---------------+

</code></pre><h3 id="Docker-Registry"><a href="#Docker-Registry" class="headerlink" title="Docker Registry"></a>Docker Registry</h3><p>Docker仓库分为公有和私有，放着一些已有的镜像，官方的docker registry是<a href="https://www.docker.com/products/docker-hub">Docker Hub</a>。</p>
<h3 id="Namespaces"><a href="#Namespaces" class="headerlink" title="Namespaces"></a>Namespaces</h3><p>C++中有namespace这个概念，它实现了代码块的封装，更重要的是代码的隔离，使得不同namespace下可以有相同的变量名但意义不同。在linux里，namespace是一个重要的特性，提供了系统资源的隔离，包括进程/网络/文件系统等。linux实现namespace的重要目的就是为了实现轻量级的虚拟化，也就是容器（linux里的lxc了解一下）。在同一namespace下的进程可以感知彼此的变化，而不能发现其他进程，从而使得一个namespace下的进程认为自身处于一个独立的系统中，便达到了独立和隔离的目的。<br>Docker目前用到了以下几种namespace进行资源隔离。</p>
<ul>
<li>PID， Process ID, 进程隔离；</li>
<li>NET， Network， 网络隔离；</li>
<li>IPC， InterProcess Communication， 跨进程通信访问隔离；</li>
<li>MNT， Mount， 挂载点隔离；</li>
<li>UTS， Unix Timesharing System， 内核和版本标识隔离；</li>
<li>USER, 用户和组隔离；</li>
</ul>
<p>而隔离资源的管理就需要用到Control Groups</p>
<h3 id="Control-Groups"><a href="#Control-Groups" class="headerlink" title="Control Groups"></a>Control Groups</h3><p>Control groups是linux提供的限制/记录/隔离主机物理资源的机制，简称cgroups，为了更好的管理容器，cgroups在2007年并入到linux kernel中。没有cgroups，就没有容器。<br>cgroups主要负责容器相关的以下内容：</p>
<ul>
<li>资源限制，比如为进程组设置一个内存使用的上限；</li>
<li>优先级设定，比如为某些进程组设定更大的cpu和内存资源。</li>
<li>资源计量，比如计算进程组使用了多少系统资源。</li>
<li>资源控制，比如将进程组挂起和恢复。</li>
</ul>
<p>正是因为namespaces和cgroups，Docker的容器才拥有了以下能力：</p>
<ul>
<li>文件系统隔离：每个容器都有自己的rootfs；</li>
<li>进程隔离： 每个容器都运行在自己的进程环境中；</li>
<li>网络隔离： 容器间的虚拟网络接口和IP地址都是分离的；</li>
<li>资源隔离和分组： cgroups将CPU和内存等资源独立分配给每个不同的Docker容器。</li>
</ul>
<h2 id="Dockerfile指令"><a href="#Dockerfile指令" class="headerlink" title="Dockerfile指令"></a>Dockerfile指令</h2><p>类似于Makefile， Docker可以根据Dockerfile来构建镜像。Dockerfile是一个文本文件，每一行都是一个Dockerfile指令。接着使用docker build命令就可以构建出一个docker镜像了。Dockerfile是自动化运维的关键。</p>
<h3 id="指令格式"><a href="#指令格式" class="headerlink" title="指令格式"></a>指令格式</h3><p>注释</p>
<pre><code># Comment 这是注释
</code></pre><p>指令</p>
<pre><code>INSTRUCTION arguments
</code></pre><p>样例</p>
<pre><code>FROM ubuntu:16:04
LABEL author=fwz version=1.0.1
WORKDIR /root/myapp
COPY myapp .
RUN apt update \
    &amp;&amp; apt install -y python3 python3-pip
    &amp;&amp; pip3 install -r requirement.txt
EXPOSE 8000
ENTRYPOINT [&quot;/usr/bin/python3&quot;, &quot;/root/app/manage.py&quot;, &quot;runserver&quot;]
</code></pre><h3 id="FROM"><a href="#FROM" class="headerlink" title="FROM"></a>FROM</h3><p>FROM指令指定了一个基础镜像，接下来的指令都是基于这个基础镜像进行构建。每个Dockerfile都必须包含FROM指令。如果FROM指定的基础镜像不在本地，则会从Dockerhub上拉取。</p>
<pre><code>FROM ubuntu:16:04
</code></pre><pre><code>FROM python:3.7
</code></pre><h3 id="RUN"><a href="#RUN" class="headerlink" title="RUN"></a>RUN</h3><p>RUN指令是构建时执行的指令，。格式是<code>RUN &lt;command&gt;</code>或者<code>RUN [&#39;executable&#39;, &#39;param1&#39;, &#39;param2&#39;, ...]</code>，RUN指令默认使用shell执行命令，即<code>/bin/sh -c</code>执行命令，如果想使用不同的shell，比如<code>bash</code>，那么可以像这么写：</p>
<pre><code>RUN [&#39;/bin/bash&#39;, &#39;-c&#39; &#39;python3 bootstrap.py&#39;]
</code></pre><p>而且最好RUN指令的内容都写在同一行，防止ufs的层数过多。</p>
<h3 id="CMD"><a href="#CMD" class="headerlink" title="CMD"></a>CMD</h3><p>CMD指令是容器启动时执行的指令，可以包含参数，比如：</p>
<pre><code>CMD [&quot;python3&quot;, &quot;manage.py&quot;, &quot;runserver&quot;, &quot;0.0.0.0:8000&quot;]
</code></pre><h3 id="EXPOSE"><a href="#EXPOSE" class="headerlink" title="EXPOSE"></a>EXPOSE</h3><p>用于指定容器监听的内部端口号，不过可以在<code>docker run</code>的时候更改端口映射；</p>
<pre><code>EXPOSE 27017
</code></pre><h3 id="COPY"><a href="#COPY" class="headerlink" title="COPY"></a>COPY</h3><p>把文件从本地复制到容器中</p>
<pre><code>COPY application.yml /app/
</code></pre><h3 id="ENTRYPOINT"><a href="#ENTRYPOINT" class="headerlink" title="ENTRYPOINT"></a>ENTRYPOINT</h3><p>和CMD类似，也是容器启动时执行的命令，不过可以在容器启动即<code>docker run</code>时提供参数</p>
<pre><code>ENTRYPOINT [&quot;java&quot;, &quot;app.jar&quot;]
</code></pre><h3 id="LABEL"><a href="#LABEL" class="headerlink" title="LABEL"></a>LABEL</h3><p>记录容器相关的变量，<code>docker inspect</code>时可以看到</p>
<pre><code>LABEL author=&quot;菜徐坤&quot; version=&quot;7.7.7&quot;
</code></pre>
        
    

    
</div>


                

                <!-- Post Comments -->
                
                    
                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/2019/07/05/Netty/" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/2019/06/18/Config-Center-Apollo/" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.png);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/avatar.png" alt="FWZ's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        youremail@email.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="#" target="_blank" title="Email Me">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        Email Me
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2019/09/">九月 2019<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2019/08/">八月 2019<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2019/07/">七月 2019<span class="sidebar_archives-count">7</span></a></li><li><a class="sidebar_archives-link" href="/archives/2019/06/">六月 2019<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2019/01/">一月 2019<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/12/">十二月 2018<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/07/">七月 2018<span class="sidebar_archives-count">1</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/06/">六月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/05/">五月 2018<span class="sidebar_archives-count">3</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    

    <!-- Pages  -->
    

    <!-- Article Number  -->
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->

    <a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
            主题 - Material
            <span class="sidebar-badge badge-circle">i</span>
        </div>
    </a>


<!-- Help & Support -->
<!--

-->

<!-- Feedback -->
<!--

-->

<!-- About Theme -->
<!--

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div id="back-to-top" class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
    <!-- Paradox Footer Left Section -->
    <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    
        <a href="https://twitter.com/twitter" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-twitter">
                <span class="visuallyhidden">Twitter</span>
            </button><!--
     --></a>
    

    <!-- Facebook -->
    
        <a href="https://www.facebook.com/facebook" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-facebook">
                <span class="visuallyhidden">Facebook</span>
            </button><!--
     --></a>
    

    <!-- Google + -->
    
        <a href="https://www.google.com/" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-gplus">
                <span class="visuallyhidden">Google Plus</span>
            </button><!--
     --></a>
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    
    
    <!-- V2EX -->
    
</div>


    <!--Copyright-->
    <div id="copyright">
        Copyright&nbsp;©
        <script
            type="text/javascript">var fd = new Date(); document.write("&nbsp;" + fd.getFullYear() + "&nbsp;");</script>
        fengweizan's BLOG
        
    </div>

    <!-- Paradox Footer Right Section -->

    <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

    <div class="mdl-mini-footer--right-section">
        <div>
            <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank"
                    class="footer-develop-a">Hexo</a></div>
            <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material"
                    target="_blank" class="footer-develop-a">Material</a></div>
        </div>
    </div>
    
</footer>



                    <!-- Import JS File -->

    <script>lsloader.load("lazyload_js","/js/lazyload.min.js?1BcfzuNXqV+ntF6gq+5X3Q==", true)</script>



    <script>lsloader.load("js_js","/js/js.min.js?V/53wGualMuiPM3xoetD5Q==", true)</script>



    <script>lsloader.load("np_js","/js/nprogress.js?pl3Qhb9lvqR1FlyLUna1Yw==", true)</script>


<script type="text/ls-javascript" id="NProgress-script">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>













<!-- UC Browser Compatible -->
<script>
	var agent = navigator.userAgent.toLowerCase();
	if(agent.indexOf('ucbrowser')>0) {
		document.write('<link rel="stylesheet" href="/css/uc.css">');
	   alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
	}
</script>

<!-- Import prettify js  -->

    
        
            <script>lsloader.load("prettify_js","/js/prettify.min.js?WN07fivHQSMKWy7BmHBB6w==", true)</script>
        
    



<!-- Window Load -->
<!-- add class for prettify -->
<script type="text/ls-javascript" id="window-load">
    $(window).on('load', function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });

    
        
            $(function() {
                $('pre').addClass('prettyprint linenums').attr('style', 'overflow:auto;');
                prettyPrint();
                })
        
    
    
</script>

<!-- MathJax Load-->


<!-- Bing Background -->

<script type="text/ls-javascript" id="Bing-Background-script">
    queue.offer(function(){
        $('body').attr('data-original', 'https://api.i-meto.com/bing?');
    });
</script>


<script type="text/ls-javascript" id="lazy-load">
    // Offer LazyLoad
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    // Start Queue
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

<!-- Custom Footer -->



<script>
    (function(){
        var scriptList = document.querySelectorAll('script[type="text/ls-javascript"]')

        for (var i = 0; i < scriptList.length; ++i) {
            var item = scriptList[i];
            lsloader.runInlineScript(item.id,item.id);
        }
    })()
console.log('\n %c © Material Theme | Version: 1.5.2 | https://github.com/viosey/hexo-theme-material %c \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-left-radius:5px;border-bottom-left-radius:5px;', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-right-radius:5px;border-bottom-right-radius:5px;');
</script>

                </main>
            </div><!-- hexo-inject:begin --><!-- hexo-inject:end -->
        </body>
    
</html>
